﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Windows;
using System.Windows.Input;
using GalaSoft.MvvmLight.Command;
using MSH.Common.Classes;
using MSH.Common.DAO.Results;
using WP7Client.Classes;
using WP7Client.Helpers;
using WP7Client.ServerManager;
using System.Linq;

namespace WP7Client.Controller
{
    public class ConversationsController : BaseController
    {
        #region Members

        private ObservableCollection<Conversation> _Conversations;

        #endregion

        #region Get&Set

        public ICommand DeleteChatCommand
        {
            get;
            internal set;
        }

        public ICommand ShowChatCommand
        {
            get;
            internal set; 
        }

        public ObservableCollection<Conversation> Conversations
        {
            get { return _Conversations; }
            set { 
                _Conversations = value;
                OnPropertyChanged("Converstations");
            }
        }

        public Boolean AreThereUnreadMessages
        {
            get
            {
                if (Conversations != null)
                {
                    foreach (Conversation c in Conversations)
                    {
                        if (c.Messages != null)
                        {
                            foreach (ChatMessage cm in c.Messages)
                            {
                                if (cm.IsRead == false)
                                {
                                    return true;
                                }
                            }
                        }
                    }
                }
                return false;
            }
        }

        #endregion

        public ConversationsController()
        {
            ShowChatCommand = new RelayCommand<String>(ChatWith);
            DeleteChatCommand = new RelayCommand<String>(DeleteChat);

            Conversations = (ObservableCollection<Conversation>)IsolatedStorageHelper.GetData("Userconversations");
            if (Conversations == null)
                Conversations = new ObservableCollection<Conversation>();
        }

        public override void Update()
        {
            base.Update();
            NewIncomingMessages();
        }

        public void Save()
        {
            IsolatedStorageHelper.SetData("Userconversations", Conversations);
            Conversations.Clear();
        }

        public void Unloaded()
        {
            Save();
        }

        /// <summary>
        /// Haal een conversatie met een bepaalde gebruiker op
        /// </summary>
        /// <param name="username">Gebruiker waarmee de conversatie is</param>
        /// <returns>De al bestaande conversatie, of null</returns>
        private Conversation FindConversation(String username)
        {
            if (Conversations == null || username == null)
                return null;

            foreach (Conversation c in Conversations)
            {
                if (c.StorageIdentifier == (UserHelper.Username + ".Conversation." + username))
                    return c;
            }
            return null;
        }

        /// <summary>
        /// Start een conversatie met een gebruiker
        /// </summary>
        /// <param name="username">Gebruiker waarmee een conversatie gestart word.</param>
        public void ChatWith(String username)
        {
            lock (Conversations)
            {
                Conversation conversation = FindConversation(username);
                if (conversation == null)
                {
                    conversation = new Conversation(UserHelper.Username + ".Conversation." + username, username);
                    Conversations.Add(conversation);
                }

                ControllerHelper.ChatController.Conversation = conversation;
                NavigationHelper.NavigateTo("/UserInterface/Pages/ChatPage.xaml");

                OnPropertyChanged("Conversations");
            }
        }

        /// <summary>
        /// Verwijder een openstaande conversatie
        /// </summary>
        /// <param name="username">Gebruiker waarmee de conversatie was</param>
        public void DeleteChat(String username)
        {
            lock (Conversations)
            {
                Conversation conversationToDelete = FindConversation(username);

                if (ControllerHelper.ChatController.Conversation == conversationToDelete)
                    ControllerHelper.ChatController.Conversation = null;

                if (conversationToDelete != null)
                    Conversations.Remove(conversationToDelete);

                OnPropertyChanged("Conversations");
            }
        }

        /// <summary>
        /// Ophalen van binnenkomende chat berichten
        /// </summary>
        public void NewIncomingMessages()
        {
            Loading = true;

            HttpGet getMessagesHttpGet = new HttpGet(String.Format(GlobalHelper.Url + "GetChatMessages/{0}", UserHelper.Token), typeof(GetChatMessagesResult));
            getMessagesHttpGet.FinishedGet += MessageReceived;
        }

        /// <summary>
        /// Ontvangen bericht in de juiste conversation plaatsen
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        public void MessageReceived(object sender, EventArgs e)
        {
            try
            {
                HttpGet get = sender as HttpGet;
                if (get == null || get.resultObject == null)
                    return;

                GetChatMessagesResult result = (GetChatMessagesResult)get.resultObject;
                if (result != null && result.TokenValidationResult == TokenValidationResultEnum.Valid)
                {
                    List<MSH.Common.DAO.ChatMessage> messages = result.ChatMessages;
                    if (messages == null)
                        throw new Exception("no messages");

                    Deployment.Current.Dispatcher.BeginInvoke(
                    delegate
                    {

                        foreach (MSH.Common.DAO.ChatMessage message in messages)
                        {
                            DateTime timeStamp = new DateTime(message.MessageTimestamp.Year, message.MessageTimestamp.Month, message.MessageTimestamp.Day, message.MessageTimestamp.Hour, message.MessageTimestamp.Minute, message.MessageTimestamp.Second, message.MessageTimestamp.Millisecond, DateTimeKind.Utc);
                            message.MessageTimestamp = timeStamp.ToLocalTime();
                            //Conversations.Clear();
                            Conversation conversation = FindConversation(message.FromUsername);

                            if (conversation != null)
                            {
                                lock (conversation)
                                {
                                    conversation.Messages.Add(new ChatMessage(message.Message, true, message.MessageTimestamp));
                                    OnPropertyChanged("Messages");
                                }
                            }
                            else
                            {
                                lock (Conversations)
                                {
                                    conversation = new Conversation((UserHelper.Username + ".Conversation." + message.FromUsername), message.FromUsername);
                                    conversation.Messages.Add(new ChatMessage(message.Message, true, message.MessageTimestamp));
                                    Conversations.Add(conversation);
                                    OnPropertyChanged("Messages");
                                }
                            }

                            if (conversation != null)
                            {
                                var sortedOC = from item in conversation.Messages orderby item.Timestamp select item;
                                List<ChatMessage> cmList = sortedOC.ToList();
                                conversation.Messages.Clear();
                                foreach (var cm in cmList)
                                {
                                    conversation.Messages.Add(cm);
                                }
                            }

                            if (ControllerHelper.ChatController != null && ControllerHelper.ChatController.Conversation != null && ControllerHelper.ChatController.Conversation == conversation)
                            {
                                //Geen melding geven, het correcte gesprek is reeds geopent.
                            }
                            else
                            {
                                //Geef melding van nieuw bericht.
                            }

                            if (ControllerHelper.ChatController != null && ControllerHelper.ChatController.ChatPage != null)
                                ControllerHelper.ChatController.ChatPage.RefreshMessagesList();

                            //Update eventueel de melding van nieuwe berichten
                            //ControllerHelper.OverviewController.OverviewPage.TextBlockNewMessages.GetBindingExpression(TextBlock.VisibilityProperty).UpdateSource();
                            if (ControllerHelper.OverviewController.GotNewUnreadMessages)
                                ControllerHelper.OverviewController.OverviewPage.TextBlockNewMessages.Visibility = Visibility.Visible;
                            else
                                ControllerHelper.OverviewController.OverviewPage.TextBlockNewMessages.Visibility = Visibility.Collapsed;
                        }
                    });
                }
                else
                {

                }

            }
            catch (Exception ex) 
            { 
            
            }
            finally 
            { 
                OnPropertyChanged("Conversations");
                Loading = false;
            }
        }
    }
}
